package main

import (
	"context"
	"fmt"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/sirupsen/logrus"
	"homework/1212/httpserver/metric"
	"io"
	"math/rand"
	"net/http"
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"
	"time"
)

func main() {
	//注册指标
	metric.Register()
	//路由
	mux := http.NewServeMux()
	mux.HandleFunc("/", rootHandler)
	mux.HandleFunc("/healthz", HealthzHandler)
	mux.Handle("/metric", promhttp.Handler())

	//监听端口
	httpSrv := http.Server{
		Addr:    ":80",
		Handler: mux,
	}


	//优雅停止
	done := make(chan os.Signal, 1)
	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		if err := httpSrv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			logrus.Fatalf("listen: %s\n", err)
		}
	}()
	logrus.Info("Server Started")
	<-done
	logrus.Info("Server Stopped")
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer func() {
		// extra handling here
		cancel()
	}()

	if err := httpSrv.Shutdown(ctx); err != nil {
		logrus.Fatalf("Server Shutdown Failed:%+v", err)
	}
	logrus.Info("Server Exited Properly")

}

func HealthzHandler(w http.ResponseWriter, r *http.Request) {
	if len(r.Header) > 0 {
		for k, v := range r.Header {
			fmt.Printf("req header: %s=%s\n", k, v)
			vv := strings.Join(v, ",")
			w.Header().Set(k, vv)
		}
		w.Header().Set("go-version", runtime.Version())
		w.Header().Set("test", "test")
		w.WriteHeader(200)
		w.Write([]byte("hello world!\n")) //问题：不清楚为什么在14-18行放开后，此行就不生效了？
	}

}

func randInt(min int, max int) int {
	rand.Seed(time.Now().UTC().UnixNano())
	return min + rand.Intn(max-min)
}

func rootHandler(w http.ResponseWriter, r *http.Request) {
	logrus.Println("entering root handler")
	timer := metric.NewTimer()
	defer timer.ObserveTotal()
	user := r.URL.Query().Get("user")
	if user != "" {
		io.WriteString(w, fmt.Sprintf("hello [%s]\n", user))
	} else {
		io.WriteString(w, "hello [stranger]\n")
	}
	io.WriteString(w, "===================Details of the http request header:============\n")
	for k, v := range r.Header {
		io.WriteString(w, fmt.Sprintf("%s=%s\n", k, v))
	}
	delay := randInt(10, 2000)
	time.Sleep(time.Millisecond * time.Duration(delay))
	req,err:=http.NewRequest("GET","http://httpserver1",nil)
	if err!=nil{
		fmt.Printf("#{err}")
	}
	lowerCaseHeader:=make(http.Header)
	for key,value:= range r.Header{
		lowerCaseHeader[strings.ToLower(key)]=value
	}
	logrus.Infof("headers:", lowerCaseHeader)
	req.Header=lowerCaseHeader
	client :=&http.Client{}
	resp,err:=client.Do(req)
	if err!=nil{
		logrus.Info("HTTP get failed",err)
	}else {
		logrus.Info("HTTP get succeeded")
	}
	if resp!=nil{
		resp.Write(w)
	}

	logrus.Infof("Respond in %d ms", delay)
}
